package com.wsx.ones.sharding.user;

import com.dangdang.ddframe.rdb.sharding.api.ShardingValue;
import com.dangdang.ddframe.rdb.sharding.api.strategy.table.SingleKeyTableShardingAlgorithm;
import com.google.common.collect.Range;
import com.wsx.ones.finalstr.common.CommonFinalUtil;
import com.wsx.ones.finalstr.common.UserShardingUtil;

import java.util.Collection;
import java.util.LinkedHashSet;

/**
 * 用户分表的操作
 * 用户的主键id是long型的，存储的数据，我们采用的策略是均匀分布
 *
 * Created by wangshuaixin on 16/12/20.
 */
public class UserKeyTableSharding implements SingleKeyTableShardingAlgorithm<Long> {

    @Override
    public String doEqualSharding(Collection<String> availableTargetNames, ShardingValue<Long> shardingValue) {
        //遍历所有可用的表
        for (String table : availableTargetNames) {
            //对主键进行取模算法来匹配用户表的后缀
            if (table.endsWith(
                    shardingValue.getValue() % UserShardingUtil.USER_TABLES_MOD
                            + CommonFinalUtil.STRING_EMPTY)) {
                return table;
            }
        }
        throw new IllegalArgumentException();
    }

    @Override
    public Collection<String> doInSharding(Collection<String> availableTargetNames, ShardingValue<Long> shardingValue) {
        //定义返回数据表的集合
        Collection<String> tables = new LinkedHashSet<String>(availableTargetNames.size());
        //遍历where条件中的in值
        for (Long value : shardingValue.getValues()) {
            //遍历所有可用的数据表
            for (String table : availableTargetNames) {
                //对用户数据进行取模算法计算匹配表的后缀
                if (table.endsWith(value % UserShardingUtil.USER_TABLES_MOD + CommonFinalUtil.STRING_EMPTY)) {
                    tables.add(table);
                }
            }
        }
        return tables;
    }

    @Override
    public Collection<String> doBetweenSharding(Collection<String> availableTargetNames, ShardingValue<Long> shardingValue) {
        //定义返回数据表的集合
        Collection<String> tables = new LinkedHashSet<String>(availableTargetNames.size());
        //获得where语句中的between中的属性
        Range<Long> ranges = shardingValue.getValueRange();
        //遍历between中的开始和结束端的值
        for (Long value = ranges.lowerEndpoint(); value <= ranges.upperEndpoint(); value++) {
            //遍历所有可用的数据表
            for (String table : availableTargetNames) {
                //对用户数据进行取模算法计算匹配表的后缀
                if (table.endsWith(value % UserShardingUtil.USER_TABLES_MOD + CommonFinalUtil.STRING_EMPTY)) {
                    tables.add(table);
                }
            }
        }
        return tables;
    }
}
